package com.task.manage.system.service.impl;

import com.task.manage.common.exception.ServiceException;
import com.task.manage.common.utils.ShiroUtils;
import com.task.manage.system.domain.*;
import com.task.manage.system.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 获取任务规则器
 */
@Service
public class RequireTaskServiceImpl implements RequireTaskService {

    @Resource
    private ITaskReveiveRecordService taskReveiveRecordService;

    @Resource
    private IMerchantTaskService merchantTaskService;

    @Resource
    private ITaskManageService taskManageService;

    @Resource
    private IMerchantTaskPriorityService merchantTaskPriorityService;


    @Override
    @Transactional
    public StringBuffer requirePersonTask(PersonnelData personnelData) {
        Long id=personnelData.getId();
        StringBuffer stringBuffer=new StringBuffer();
        //先要从商家任务表取出能做的任务 任务数大于0
        List<MerchantTask> merchantTaskList=merchantTaskService.selectTaskList();
        if(CollectionUtils.isEmpty(merchantTaskList)){
            stringBuffer.append("无可用任务数,请先配置商家任务");
            return stringBuffer;
        }
        //获取该人员31天内任务领取记录
        List<TaskReveiveRecord> taskReveiveRecords=merchantTaskService.selectaskRecordList(id);
        //说明该用户还没有任何任务记录 随机派发一个任务出来 随机派发任务需要遵从
        Map<Long,Long> mapPriority=new HashMap<>();
        if(CollectionUtils.isEmpty(taskReveiveRecords)){
            //这里要去取出优先级最高的任务
            MerchantTask merchantTask=this.getPriorityTask(merchantTaskList,mapPriority);
            if (merchantTask==null){
                stringBuffer.append(String.format("%s没有获取到有效任务",personnelData.getPersonName())+"\n");
                return stringBuffer;
            }else{
                dealTaskProcess(personnelData.getId(), merchantTask);
            }
        }else{
            //判断该人员是否还有领取任务的次数
            if(taskReveiveRecords.size()>=personnelData.getTaskLimit()){
                stringBuffer.append(String.format("%s已达到最大任务数;",personnelData.getPersonName())+"\n");
                return stringBuffer;
            }
            //说明该用户有任务记录 一个月内店铺名字重复的需要排除掉
            merchantTaskList=merchantTaskList.stream() .filter(merchantTask -> taskReveiveRecords.stream()
                    .noneMatch(taskReveiveRecord -> taskReveiveRecord.getStoreName().equals(merchantTask.getStoreName())))
                    .collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(merchantTaskList)){
                //随机获取一个任务
                //这里要去取出优先级最高的任务
                MerchantTask merchantTask=this.getPriorityTask(merchantTaskList,mapPriority);
                if (merchantTask==null){
                    stringBuffer.append(String.format("%s没有获取到有效任务;",personnelData.getPersonName())+"\n");
                    return stringBuffer;
                }else{
                    dealTaskProcess(personnelData.getId(), merchantTask);
                }
            }else{
                stringBuffer.append(String.format("%s已没有可分派任务;",personnelData.getPersonName())+"\n");
                return stringBuffer;
            }
        }
        stringBuffer.append(String.format("%s成功领取任务;",personnelData.getPersonName())+"\n");
        return stringBuffer;
    }

    private MerchantTask getPriorityTask(List<MerchantTask> merchantTaskList,Map<Long,Long> mapPriority) {
        MerchantTask task=merchantTaskList.get(0);
        MerchantTask minMerchatTask=new MerchantTask();
        //查询任务优先级表
        Long taskId=task.getId();
        MerchantTaskPriority merchantTaskPriority=merchantTaskPriorityService.getMerchantTaskPriority(taskId);
        if(merchantTaskPriority==null){
            //说明该任务没有被领取过  任务的优先级最高
            merchantTaskList.clear();
            Long priority=0L;
            mapPriority.put(taskId,priority);
            return task;
        }else{
            //该任务已被领取过 则要计算及对比与其他任务的优先级
            Long priority=merchantTaskPriority.getPriorityNum();
            mapPriority.put(merchantTaskPriority.getMerchatTaskId(),priority);
            merchantTaskList.remove(task);
            while (!CollectionUtils.isEmpty(merchantTaskList)){
                //这里需要递归调用
                getPriorityTask( merchantTaskList, mapPriority);

            }
            // 遍历 mapPriority，找到最小的 priority 对应的 key
            long minPriority = Long.MAX_VALUE;
            Long minKey = null;
            for (Map.Entry<Long, Long> entry : mapPriority.entrySet()) {
                long priorityExists = entry.getValue();
                if (priorityExists < minPriority) {
                    minPriority = priorityExists;
                    minKey = entry.getKey();
                }
            }
            if (minKey != null){
                //minKey 即使优先级最低的task
                minMerchatTask=merchantTaskService.selectMerchantTaskById(minKey);
            }
        }
        return minMerchatTask;
    }

    /**
     * 通用处理任务逻辑
     * @param personId
     * @param merchantTask
     */
    private void dealTaskProcess(Long personId, MerchantTask merchantTask) {
        Long mercId=merchantTask.getMercId();
        //任务领取记录表生成一条记录
        TaskReveiveRecord taskReveiveRecord=new TaskReveiveRecord();
        taskReveiveRecord.setPersionId(personId);
        taskReveiveRecord.setMerchatTaskId(merchantTask.getId());
        taskReveiveRecord.setStoreName(merchantTask.getStoreName());
        //获取id最大的值
        Long maxId=taskReveiveRecordService.selectMaxId();
        taskReveiveRecord.setId(maxId);
        taskReveiveRecordService.insertTaskReveiveRecord(taskReveiveRecord);
        //任务管理器中生成一条记录
        TaskManage taskManage=new TaskManage();
        taskManage.setPersonId(personId);
        taskManage.setTaskRecordId(maxId);
        taskManage.setMercId(mercId);
        taskManage.setUserId(ShiroUtils.getUserId());
        taskManageService.insertTaskManage(taskManage);
        //任务数减1
        merchantTask.setTaskCounts(merchantTask.getTaskCounts()-1);
        merchantTaskService.updateMerchantTask(merchantTask);
        //商家任务优先级表 插入一条记录
        MerchantTaskPriority merchantTaskPriority=merchantTaskPriorityService.getMerchantTaskPriority(merchantTask.getId());
        if(merchantTaskPriority!=null){
            Long priorityNum = merchantTaskPriority.getPriorityNum() == null ? 0L : merchantTaskPriority.getPriorityNum();
            Long currentPriority=priorityNum+1;
            merchantTaskPriority.setPriorityNum(currentPriority);
            merchantTaskPriorityService.updateMerchantTaskPriority(merchantTaskPriority);
        }else{
            merchantTaskPriority=new MerchantTaskPriority();
            merchantTaskPriority.setPriorityNum(1L);
            merchantTaskPriority.setMerchatTaskId(merchantTask.getId());
            merchantTaskPriorityService.insertMerchantTaskPriority(merchantTaskPriority);
        }

    }
}
